/// @tags: SA SuffixArray
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <set>

int const N = 2e4 + 5, M = 1e6 + 5;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

int n, m = M - 1, k, top;
int a[N], sa[N], rk[M], cnt[M], tmp[N], ht[N], q[N];
std::multiset<int> set;

inline void sort() {
  memset(cnt, 0, sizeof(int) * (m + 1));
  for (int i = 1; i <= n; ++i) ++cnt[rk[i]];
  for (int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
  for (int i = n; i; --i) sa[cnt[rk[tmp[i]]]--] = tmp[i];
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P2852 [USACO06DEC]Milk Patterns G.in", "r", stdin);
  freopen("P2852 [USACO06DEC]Milk Patterns G.out", "w", stdout);
#endif
#endif

  read(n), read(k);
  for (int i = 1; i <= n; ++i) read(a[i]), rk[i] = a[i], tmp[i] = i;
  sort();
  for (int l = 1, p = 0; p < n; l <<= 1, m = p) {
    p = 0;
    for (int i = n - l + 1; i <= n; ++i) tmp[++p] = i;
    for (int i = 1; i <= n; ++i)
      if (sa[i] > l) tmp[++p] = sa[i] - l;
    sort();
    memcpy(tmp, rk, sizeof(tmp));
    rk[sa[1]] = p = 1;
    for (int i = 2; i <= n; ++i) {
      rk[sa[i]] = (tmp[sa[i]] == tmp[sa[i - 1]] && tmp[sa[i] + l] == tmp[sa[i - 1] + l])
                      ? p
                      : ++p;
    }
  }
  for (int i = 1, k = 0; i <= n; ++i) {
    if (k) --k;
    while (a[i + k] == a[sa[rk[i] - 1] + k]) ++k;
    ht[rk[i]] = k;
  }
  int l = 1, r = 1, ans = 0;
  for (int i = 1; i <= n; ++i) {
    while (l <= r && ht[i] < ht[q[r]]) --r;
    q[++r] = i;
    while (l < r && q[l] <= i - k + 1) ++l;
    ans = std::max(ans, ht[q[l]]);
  }
  printf("%d", ans);
  return 0;
}